package com.hyxt.utils;

import com.hyxt.utils.bytes.BytesUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class T809_Util {
    private static Log log = LogFactory.getLog(T809_Util.class);
    /**
     * @Description a) 若数据内容中有出现字符0x5b的，需替换为字符0x5a紧跟字符0x01; b)
     *              若数据内容中有出现字符0x5a的，需替换为字符0x5a紧跟字符0x02; c)
     *              若数据内容中有出现字符0x5d的，需替换为字符0x5e紧跟字符0x01; d)
     *              若数据内容中有出现字符0x5e的，需替换为字符0x5e紧跟字符0x02.
     * @param :args
     * @return
     * @throws Exception
     */
    public static byte[] reverseEscapeData(byte[] data) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] reverseEscapedDatabytes = null;
        // 如果数据头为5b
        if (data[0] == 0x5b) {
            bos.write(0x5b);
        } else {
            // 如果不是5b，关闭流
            closeBos(bos);
        }

        for (int i = 1; i < data.length - 1; i++) {
            switch (data[i]) {
                // 判断5a后面的数据，
                case 0x5a:
                    // 进行反转义
                    if (data[i + 1] == 0x01) {
                        bos.write(0x5b);
                        i++;
                        break;
                        // 反转义
                    } else if (data[i + 1] == 0x02) {
                        bos.write(0x5a);
                        i++;
                        break;
                    }
                    bos.write(data[i]);
                    break;
                // 关闭流，抛出异常
                // closeBos(bos);
                // throw new ProtocolEscapeExeption(ByteUtil.bytes2BCDStr(data));
                // 判断5e后面的数据，
                case 0x5e:
                    if (data[i + 1] == 0x01) {
                        // 进行反转义
                        bos.write(0x5d);
                        i++;
                        break;
                    } else if (data[i + 1] == 0x02) {
                        // 反转义
                        bos.write(0x5e);
                        i++;
                        break;
                    }

                    bos.write(data[i]);
                    // 关闭流，抛出异常
                    // closeBos(bos);
                    // throw new
                    // ProtocolEscapeExeption(ByteUtil.bytes2BCDStr(data));
                default:
                    bos.write(data[i]);
            }
        }
        // 判断尾标识
        if (data[data.length - 1] == 0x5d) {
            bos.write(0x5d);
        } else {
            // 关闭流
            closeBos(bos);
        }
        // 获取反转义后的数据
        reverseEscapedDatabytes = bos.toByteArray();
        closeBos(bos);
        return reverseEscapedDatabytes;
    }
    /**
     * @Description 关闭流
     * @param os
     * @return void
     * @throws Exception
     */
    private static void closeBos(OutputStream os) {
        try {
            os.close();
        } catch (IOException e) {
            log.warn("", e);
        }
    }
    /**
     * @Description 检查crc校验码方法
     * @param data
     * @return void
     * @throws Exception
     */
    public static byte[] check(byte[] data) {

        byte[] checked = new byte[2];

        int crc = 0xFFFF;// 初始值
        short polynomial = 0x1021;// 0001 0000 0010 0001 (0,5,12)

        for (int j = 1; j < data.length - 3; ++j) {
            for (int i = 0; i < 8; i++) {
                // 移位操作
                boolean bit = ((data[j] >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                // 算出crc码
                if (c15 ^ bit) {
                    crc ^= polynomial;
                }
            }
        }
        crc &= 0xFFFF;
        checked = BytesUtil.int2bytes2(crc);
        return checked;
    }
}
